/*****************************************************
//Filename:     comutil.c							//
//Version:	    V1.1								//
//Released:		2011-06-25 08:00					//
//Author:		Hua Weidong							//
//Description:  Communication utils.

//         READ ME
**2011-06-25 08:00
Modifier: Hua Weidong
1. Versiion V1.1 is released.
2. Add functions:
    comutil_ReadBufWaitChar2
    comutil_ReadBufWaitTag2
    comutil_ReadBufWaitStr2

**2010-06-04 10:00
Creator: Hua Weidong
1.Version V1.0 is released.


****************************************************/
#include	<stdlib.h>
#include	<string.h>

#include	"comutil.h"


#define	DELAY_STEP_MS	20
uint16 comutil_ReadBufWait(HANDLE handle, void *buf, uint16 size, uint32 startDelay, uint32 interval)
{
	uint16	i = 0, sz = size, n;
	uint32	delay = 0;
	uint8	*p = buf;

	if (handle == INVALID_HANDLE_VALUE)
	{
		return	0;
	}
	if (startDelay == 0)
	{
		startDelay = 1000;
	}
	if (interval == 0)
	{
		interval = 500;
	}

	while((n = com_ReadBuffer(handle, &p[i], sz)) < sz)
	{
		sz -= n;
		i += n;
		sysutil_TimeDly(DELAY_STEP_MS);

		if (n == 0)
		{
			delay += DELAY_STEP_MS;
			if (sz == size)
			{
				if (delay > startDelay)
				{
					return i;
				}
			}
			else if (delay > interval)
			{
				return	i;
			}
		}
		else
		{
			delay = 0;
		}
	}
	return i + n;
}

/*uint16 comutil_ReadBufWaitChar(HANDLE handle, void *buf, uint16 size, char8 ch, uint32 startDelay, uint32 interval)
{
	uint16	i = 0, sz = size, n;
	uint32	delay = 0;
	uint8	*p = buf;

	if (handle == INVALID_HANDLE_VALUE)
	{
		return	0;
	}
	if (startDelay == 0)
	{
		startDelay = 1000;
	}
	if (interval == 0)
	{
		interval = 500;
	}

	while((n = com_ReadBuffer(handle, &p[i], sz)) < sz)
	{
		sz -= n;
		i += n;
		if (i > 0 && p[i - 1] == ch)
		{
			return i;
		}
		sysutil_TimeDly(DELAY_STEP_MS);

		if (n == 0)
		{
			delay += DELAY_STEP_MS;
			if (sz == size)
			{
				if (delay > startDelay)
				{
					return i;
				}
			}
			else if (delay > interval)
			{
				return	i;
			}
		}
		else
		{
			delay = 0;
		}
	}
	return i + n;
}*/

uint16 comutil_ReadBufWaitTag(HANDLE handle, void *buf, uint16 size, void *tag, uint8 tagSize, uint32 startDelay, uint32 interval)
{
	uint16	i = 0, sz = size, n;
	uint32	delay = 0;
	uint8	*p = buf;

	if (handle == INVALID_HANDLE_VALUE)
	{
		return	0;
	}
	if (startDelay == 0)
	{
		startDelay = 1000;
	}
	if (interval == 0)
	{
		interval = 500;
	}

	while((n = com_ReadBuffer(handle, &p[i], sz)) < sz)
	{
		sz -= n;
		i += n;
		
		if (i >= tagSize)
		{
			if (memcmp(&p[i - tagSize], tag, tagSize) == 0)
			{
				return i;
			}
		}
		sysutil_TimeDly(DELAY_STEP_MS);

		if (n == 0)
		{
			delay += DELAY_STEP_MS;
			if (sz == size)
			{
				if (delay > startDelay)
				{
					return i;
				}
			}
			else if (delay > interval)
			{
				return	i;
			}
		}
		else
		{
			delay = 0;
		}
	}
	return i + n;
}

/*uint16 comutil_ReadBufWaitStr(HANDLE handle, void *buf, uint16 size, char8 *str, uint32 startDelay, uint32 interval)
{
	return comutil_ReadBufWaitTag(handle, buf, size, str, strlen(str), startDelay, interval);
}
*/

uint16 comutil_ReadBufWait2(RECEIVE_HANDLER *handler, void *buf, uint16 size, uint32 startDelay, uint32 interval)
{
	uint16	i = 0, sz = size, n;
	uint32	delay = 0;
	uint8	*p = buf;

	if (handler == NULL)
	{
		return	0;
	}
	if (startDelay == 0)
	{
		startDelay = 1000;
	}
	if (interval == 0)
	{
		interval = 500;
	}

	while((n = handler(&p[i], sz)) < sz)
	{
		sz -= n;
		i += n;
		sysutil_TimeDly(DELAY_STEP_MS);

		if (n == 0)
		{
			delay += DELAY_STEP_MS;
			if (sz == size)
			{
				if (delay > startDelay)
				{
					return i;
				}
			}
			else if (delay > interval)
			{
				return	i;
			}
		}
		else
		{
			delay = 0;
		}
	}
	return i + n;
}

uint16 comutil_ReadBufWaitChar2(RECEIVE_HANDLER *handler, void *buf, uint16 size, char8 ch, uint32 startDelay, uint32 interval)
{
	uint16	i = 0, sz = size, n;
	uint32	delay = 0;
	uint8	*p = buf;

	if (handler == NULL)
	{
		return	0;
	}
	if (startDelay == 0)
	{
		startDelay = 1000;
	}
	if (interval == 0)
	{
		interval = 500;
	}

	while((n = handler(&p[i], sz)) < sz)
	{
		sz -= n;
		i += n;
		if (i > 0 && p[i - 1] == ch)
		{
			return i;
		}
		sysutil_TimeDly(DELAY_STEP_MS);

		if (n == 0)
		{
			delay += DELAY_STEP_MS;
			if (sz == size)
			{
				if (delay > startDelay)
				{
					return i;
				}
			}
			else if (delay > interval)
			{
				return	i;
			}
		}
		else
		{
			delay = 0;
		}
	}
	return i + n;
}

uint16 comutil_ReadBufWaitTag2(RECEIVE_HANDLER *handler, void *buf, uint16 size, void *tag, uint8 tagSize, uint32 startDelay, uint32 interval)
{
	uint16	i = 0, sz = size, n;
	uint32	delay = 0;
	uint8	*p = buf;

	if (handler == NULL)
	{
		return	0;
	}
	if (startDelay == 0)
	{
		startDelay = 1000;
	}
	if (interval == 0)
	{
		interval = 500;
	}

	while((n = handler(&p[i], sz)) < sz)
	{
		sz -= n;
		i += n;
		
		if (i >= tagSize)
		{
			if (memcmp(&p[i - tagSize], tag, tagSize) == 0)
			{
				return i;
			}
		}
		sysutil_TimeDly(DELAY_STEP_MS);

		if (n == 0)
		{
			delay += DELAY_STEP_MS;
			if (sz == size)
			{
				if (delay > startDelay)
				{
					return i;
				}
			}
			else if (delay > interval)
			{
				return	i;
			}
		}
		else
		{
			delay = 0;
		}
	}
	return i + n;
}

uint16 comutil_ReadBufWaitStr2(RECEIVE_HANDLER *handler, void *buf, uint16 size, char8 *str, uint32 startDelay, uint32 interval)
{
	return comutil_ReadBufWaitTag2(handler, buf, size, str, strlen(str), startDelay, interval);
}

//suky 2020-11-20
void comutil_Delay(DELAY_HANDLER *dlyHandler, uint32 ms)
{
	if (dlyHandler)
	{
		dlyHandler(ms);
	}
	else
	{
		uint16	n = 100;

		while (n--)
		{
			uint32	m = ms;
			while (m--);
		}
	}
}

void comutil_SendBuffer(SEND_HANDLER *sendHandler, const void *pBuff, uint16 size)
{
	if (sendHandler)
	{
		sendHandler(pBuff, size);
	}
}

void comutil_SendString(SEND_HANDLER *sendHandler, const char8 *str)
{
	comutil_SendBuffer(sendHandler, (void*)str, strlen(str));
}

uint16 comutil_ReadBuf(RECEIVE_HANDLER *rcvHandler, char8 *buf, uint16 size)
{
	if (rcvHandler)
	{
		return rcvHandler(buf, size);
	}
	return 0;
}

void comutil_ClearResponse(RECEIVE_HANDLER *rcvHandler, DELAY_HANDLER *dlyHandler)
{
#define	TEMP_LEN	20
	char8	temp[TEMP_LEN];
	uint16	n = 0;

	do
	{
		comutil_Delay(dlyHandler, 40);
		n++;
	} while (comutil_ReadBuf(rcvHandler, temp, TEMP_LEN) && (n  < 1024));
}

uint16 comutil_ReadBufWaitChar(RECEIVE_HANDLER *rcvHandler, DELAY_HANDLER *dlyHandler, char8 *buf,
	uint16 size, char8 ch)
{
	uint16	i = 0, sz = size, n;
	uint8	delayCount = 0;

	if (rcvHandler == NULL)
	{
		return	0;
	}

	while ((n = rcvHandler(&buf[i], sz)) < sz)
	{
		sz -= n;
		i += n;
		if (buf[i - 1] == ch)
		{
			return i;
		}

		comutil_Delay(dlyHandler, 20);
		if (n == 0)
		{
			delayCount ++;
			if (sz == size)
			{
				if (delayCount > 80)
				{
					return i;
				}
			}
			else if (delayCount > 50)
			{
				return	i;
			}
		}
		else
		{
			delayCount = 0;
		}
	}
	return i + n;
}

uint16 comutil_ReadBufWaitStr(RECEIVE_HANDLER *rcvHandler, DELAY_HANDLER *dlyHandler, void *buf,
	uint16 size, char8 *str, uint32 startDelay, uint32 interval)
{
	uint8	tagSize = strlen(str);
	uint8	*p = buf;
	uint16	i = 0, sz = size, n;
	uint32	delay = 0;

	if (rcvHandler == NULL)
	{
		return	0;
	}

	if (startDelay == 0)
	{
		startDelay = 1000;
	}

	if (interval == 0)
	{
		interval = 500;
	}

	while ((n = rcvHandler(&p[i], sz)) < sz)
	{
		sz -= n;
		i += n;
		if (i >= tagSize)
		{
			if (memcmp(&p[i - tagSize], str, tagSize) == 0)
			{
				return i;
			}
		}

		comutil_Delay(dlyHandler, 20);
		if (n == 0)
		{
			delay += 20;
			if (sz == size)
			{
				if (delay > startDelay)
				{
					return i;
				}
			}
			else if (delay > interval)
			{
				return	i;
			}
		}
		else
		{
			delay = 0;
		}
	}
	return i + n;
}
